package gybase01

import bean.Person

/*
Groovy 语言快速入门
https://www.jianshu.com/p/e8dec95c4326

groovy语言介绍
https://blog.csdn.net/u011861874/article/details/83657334


Groovy语言学习：groovy语言简介及基本语法
https://blog.csdn.net/happy_horse/article/details/52674146?utm_medium=distribute.pc_relevant.none-task-blog-2~default~baidujs_baidulandingword~default-0.no_search_link&spm=1001.2101.3001.4242.1

 */

class TestGroovy2 {
//    static void main(String[] args) {
    static void main(args) {

        println "hello Groovy 语言快速入门"

        //java 方式
//        int[] nums2 = {1,2,3,4,5,6}
        int[] nums = [1, 2, 3, 4, 5, 6]

        println "nums.length = ${nums.length}"

        char c1 = 'A'// 类型声明为char
        assert c1 as Character

        def c2 = 'B' as char  // 通过as将类型强制指定为char
        assert c2 instanceof Character

        def c3 = (char) 'C' // 通过类型转换
        assert c3 instanceof Character

        for (i in 1..5) {//包含范围 5
            println "i = $i"
        }

        println "-------------------------------------------------------------"

        for (k in 1..<5) { // 独占范围的,不包含5
            println "k = $k"
        }

        //hello Groovy 语言快速入门
        //nums.length = 6
        //i = 1
        //i = 2
        //i = 3
        //i = 4
        //i = 5
        //-------------------------------------------------------------
        //k = 1
        //k = 2
        //k = 3
        //k = 4


        //数组
        //Groovy定义数组的方式和定义list的方式一样，只不过声明时需要制定类型，或者通过as来强制制定类型为Array。
        //
        //Groovy不支持Java数组的初始化方式
        String[] arrStr = ['a', 'b', 'c']
        def numArr = [1, 2, 3] as int[]

        //多维数组
        def matrix3 = new Integer[2][3]


        //映射(Map)
        //映射（也称为关联数组，字典，表和散列）是对象引用的无序集合。Map集合中的元素由键值访问。 Map中使用的键可以是任何类。当我们插入到Map集合中时，需要两个值：键和值。
        //
        //Map中通过[key]或.key的方式来获取key对应的value。如果key不存在，则返回null。
        //原文链接：https://blog.csdn.net/u011861874/article/details/83657334


        //定义一个map
        def map = ['ak1': 'groovy', 'ak2': 'kotlin', 'ak3': 'android', 'ak4': 'java']
        println map
        //[ak1:groovy, ak2:kotlin, ak3:android, ak4:java]

        def ak1Value = map.get('ak1')
        println 'ak1Value = $ak1Value'
        //ak1Value = $ak1Value
        println "ak1Value = $ak1Value"
        //ak1Value = groovy

        //ak1Value = $ak1Value //单引号输入
        //ak1Value = groovy   //双引号

        //2、添加项：
        map = map + ['ak5': 'paython']
        println map['ak5']
        //paython

        println "方式一 map进行了迭代 ----------------------------------"
        //闭包（Closure）
        //闭包是用{符号括起来的代码块，它可以被单独运行或调用，也可以被命名。类似‘匿名类’或内联函数的概念。
        //闭包中最常见的应用是对集合进行迭代，下面定义了3个闭包对map进行了迭代：
        map.forEach({
            Key, value -> // key,value两个参数用于接受每个元素的键/值
                println "$Key : $value"

        })

        println "方式二 map进行了迭代 ----------------------------------"
        map.each { println it }  //it是一个关键字，代表map集合的每个元素
        println "方式三 map进行了迭代 ----------------------------------"
        map.each({ println it.getKey() + " --> " + it.getValue() })

        //方式一 map进行了迭代 ----------------------------------
        //ak1 : groovy
        //ak2 : kotlin
        //ak3 : android
        //ak4 : java
        //ak5 : paython
        //方式二 map进行了迭代 ----------------------------------
        //ak1=groovy
        //ak2=kotlin
        //ak3=android
        //ak4=java
        //ak5=paython
        //方式三 map进行了迭代 ----------------------------------
        //ak1 --> groovy
        //ak2 --> kotlin
        //ak3 --> android
        //ak4 --> java
        //ak5 --> paython


        println "类-------------------------------------------"

        //类
        def person = new Person()
//        person.setName("测试名")
        person.setName '测试名' // 不需要()号
        person.age = 20
        println person

//        def person2 = new Person(['name':'sa','age':10])
        def person2 = new Person('name': 'sa', 'age': 10)//[]号可以省略
        println person2
        //name = 测试名 , age = 20
        //name = sa , age = 10

        //？运算符
        if (person2 != null) {//避免出现空指针异常，通常需要这样的技巧
            println person2
        }

        //在groovy中，可以使用?操作符达到同样的目的：
        println person2?.name //?在这里是一个条件运算符，如果?前面的对象非null，执行后面的方法，否则什么也不做。


        println "Elvis操作符 三目运算符 --------------------------------------------------------------"
        person2.name = null

        //Elvis操作符
        //三目运算符通常以这种形式出现
        String personName1 = person2.name != null ? person2.name : "未知用户名1"

        //在groovy中，也可以简化为（因为null在groovy中可以转化为布尔值false）：
        String personName2 = person2.name ?: "未知用户名2"

        //基于“不重复”的原则，可以使用elvis操作符再次简化为：
        String personName3 = person2.name ?: "未知用户名3"

        println "personName1 = $personName1，personName2 = $personName2 , personName3 = $personName3"
        //Elvis操作符 三目运算符 --------------------------------------------------------------
        //personName1 = 未知用户名1，personName2 = 未知用户名2 , personName3 = 未知用户名3


        println "动态性 --------------------------------------------------------------"
        //动态性
        //Groovy所有的对象都有一个元类metaClass，我们可以通过metaClass属性访问该元类。通过元类，可以为这个对象增加方法（在java中不可想象）！
        // 见下面的代码，msg是一个String,通过元类，我们为msg增加了一个String 类中所没有的方法up：
        def msg = "hello!"
        println msg.metaClass
//        String.metaClass.up = {}

        (0..10).forEach{//包含10
            print it+" "
        }
        //0 1 2 3 4 5 6 7 8 9 10

        println "动态性 --------------------------------------------------------------"


        (0..<10).forEach{//不包含10
            print it+" "
        }
        //0 1 2 3 4 5 6 7 8 9

        println "动态性 --------------------------------------------------------------"

        Integer.metaClass.add1000{
            delegate + 1000
        }

        println 666.add1000()
        //1666

    }
}
